package com.youlai.boot.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.youlai.boot.common.exception.BusinessException;
import com.youlai.boot.system.enums.RoleTypeEnum;
import com.youlai.boot.system.mapper.*;
import com.youlai.boot.system.model.entity.*;
import com.youlai.boot.system.service.WasteTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.boot.system.service.TransactionService;
import com.youlai.boot.system.model.form.TransactionForm;
import com.youlai.boot.system.model.query.TransactionQuery;
import com.youlai.boot.system.model.vo.TransactionVO;
import com.youlai.boot.system.converter.TransactionConverter;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import org.springframework.transaction.annotation.Transactional;

/**
 * 交易记录表服务实现类
 *
 * @author youlaitech
 * @since 2025-02-27 15:58
 */
@Service
@RequiredArgsConstructor
public class TransactionServiceImpl extends ServiceImpl<TransactionMapper, Transaction> implements TransactionService {

    private final TransactionConverter transactionConverter;

    private final UserMapper userMapper;

    private final TransactionMapper transactionMapper;

    private final UserRoleMapper userRoleMapper;

    private final RoleMapper roleMapper;

    private final WasteTypeMapper wasteTypeMapper;
    private final WasteTypeService wasteTypeService;
    private final RequestWasteMapper requestWasteMapper;
    private final RecycleRequestMapper recycleRequestMapper;


    /**
    * 获取交易记录表分页列表
    *
    * @param queryParams 查询参数
    * @return {@link IPage<TransactionVO>} 交易记录表分页列表
    */
    @Override
    public IPage<TransactionVO> getTransactionPage(TransactionQuery queryParams) {
        Page<TransactionVO> pageVO = this.baseMapper.getTransactionPage(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams
        );
        return pageVO;
    }
    
    /**
     * 获取交易记录表表单数据
     *
     * @param id 交易记录表ID
     * @return
     */
    @Override
    public TransactionForm getTransactionFormData(Long id) {
        Transaction entity = this.getById(id);
        return transactionConverter.toForm(entity);
    }
    
    /**
     * 新增交易记录表
     *
     * @param formData 交易记录表表单对象
     * @return
     */
    @Override
    public boolean saveTransaction(TransactionForm formData) {
        Transaction entity = transactionConverter.toEntity(formData);
        return this.save(entity);
    }
    
    /**
     * 更新交易记录表
     *
     * @param id   交易记录表ID
     * @param formData 交易记录表表单对象
     * @return
     */
    @Override
    public boolean updateTransaction(Long id,TransactionForm formData) {
        Transaction entity = transactionConverter.toEntity(formData);
        return this.updateById(entity);
    }
    
    /**
     * 删除交易记录表
     *
     * @param ids 交易记录表ID，多个以英文逗号(,)分割
     * @return
     */
    @Override
    public boolean deleteTransactions(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的交易记录表数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .toList();
        return this.removeByIds(idList);
    }

    /**
     * 汇款并生成交易记录
     * 机构 --> 用户
     * 系统 --> 机构
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transactionAmountToUser(TaskAssignment taskAssignment, RecycleRequest recycleRequest) {
        // 1. 新建交易记录表
        Long orgId = taskAssignment.getOrgId();// 送至的机构（即汇款方）
        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getOrgId, orgId)).stream()
                .filter(u -> {
                    Long roleId = userRoleMapper.selectOne(new QueryWrapper<UserRole>().eq("user_id", u.getId())).getRoleId();
                    String code = roleMapper.selectById(roleId).getCode();
                    return RoleTypeEnum.RECYCLE.getCode().equals(code);
                }).toList();
        if (CollUtil.isEmpty(userList)) {
            throw new RuntimeException("找不到交易发起方");
        }

        Long fromUserId = userList.get(0).getId();
        Long toUserId = recycleRequest.getUserId();// 发起的用户（即收款方）
        Transaction entity = Transaction.builder()
                .fromUser(fromUserId)
                .fromUserStr(userMapper.selectById(fromUserId).getUsername())
                .toUser(toUserId)
                .toUserStr(userMapper.selectById(toUserId).getUsername())
                .amount(recycleRequest.getExpectReturn())
                .requestId(recycleRequest.getId())
                .build();
        transactionMapper.insert(entity);

        // 2.扣减双方余额
        User fromUser = userMapper.selectById(entity.getFromUser());
        User toUser = userMapper.selectById(entity.getToUser());

        // 判断余额
        if (fromUser.getBalance().compareTo(entity.getAmount()) < 0) {
            throw new RuntimeException("余额不足");
        }
        fromUser.setBalance(fromUser.getBalance().subtract(entity.getAmount()));
        toUser.setBalance(toUser.getBalance().add(entity.getAmount()));

        userMapper.updateById(fromUser);
        userMapper.updateById(toUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transactionAmountToOrg(Long requestId) {
        //1.计算汇款金额
        BigDecimal totalPrice = calculateOrgTotalRevenue(requestId);
        //2.1查询收款方（机构用户）
        RecycleRequest recycleRequest = recycleRequestMapper.selectById(requestId);
        Long orgId = recycleRequest.getOrgId();
        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getOrgId, orgId)).stream()
                .filter(u -> {
                    Long roleId = userRoleMapper.selectOne(new QueryWrapper<UserRole>().eq("user_id", u.getId())).getRoleId();
                    String code = roleMapper.selectById(roleId).getCode();
                    return RoleTypeEnum.RECYCLE.getCode().equals(code);
                }).toList();
        if (CollUtil.isEmpty(userList)) {
            throw new RuntimeException("找不到交易收款方");
        }
        //2.2发起方（系统管理员）
        Role role = roleMapper.selectOne(new QueryWrapper<Role>().eq("code", RoleTypeEnum.ADMIN.getCode()));
        UserRole userRole = userRoleMapper.selectOne(new QueryWrapper<UserRole>().eq("role_id", role.getId()));
        User user = userMapper.selectById(userRole.getUserId());
        //2.3创建交易记录
        Transaction entity = Transaction.builder()
                .fromUser(user.getId())
                .fromUserStr(user.getUsername())
                .toUser(userList.get(0).getId())
                .toUserStr(userList.get(0).getUsername())
                .amount(totalPrice)
                .requestId(requestId)
                .build();
        transactionMapper.insert(entity);
        //2.4汇款
        User fromUser = userMapper.selectById(entity.getFromUser());
        if (fromUser.getBalance().compareTo(entity.getAmount()) < 0) {
            throw new RuntimeException("余额不足");
        }
        fromUser.setBalance(fromUser.getBalance().subtract(entity.getAmount()));
        userMapper.updateById(fromUser);
        User toUser = userMapper.selectById(entity.getToUser());
        toUser.setBalance(toUser.getBalance().add(entity.getAmount()));
        userMapper.updateById(toUser);

    }

    /**
     * 计算机构总收益
     * @param requestId
     * @return
     */
    private BigDecimal calculateOrgTotalRevenue(Long requestId) {
        List<RequestWaste> wasteList = requestWasteMapper.selectList(new QueryWrapper<RequestWaste>().eq("request_id", requestId));
        if (CollUtil.isEmpty(wasteList)) {
            throw new RuntimeException("没有垃圾");
        }
        BigDecimal totalPrice = BigDecimal.ZERO;
        // 获取废品类型映射，增加空指针检查
        List<WasteType> wasteTypes = Optional.ofNullable(wasteTypeMapper.selectList(null))
                .orElse(Collections.emptyList());
        Map<Long, WasteType> wasteMap = wasteTypes.stream()
                .collect(Collectors.toMap(WasteType::getId, wasteType -> wasteType));
        for (RequestWaste rw : wasteList) {
            Long typeId = rw.getTypeId();
            if (typeId == null) {
                continue; // 跳过无效的废品类型
            }

            WasteType wasteType = wasteMap.get(typeId);
            if (wasteType == null) {
                continue; // 跳过无效的废品类型
            }
            BigDecimal weight = Optional.ofNullable(rw.getWeight()).orElse(BigDecimal.ZERO);
            try {
                // 计算收益
                BigDecimal actualPrice = wasteTypeService.calculateOrgRevenue(weight.multiply(new BigDecimal("0.001")), wasteType);
                totalPrice = totalPrice.add(actualPrice);
            } catch (Exception e) {
                throw new BusinessException("计算收益失败");
            }
        }
        return totalPrice;
    }

}
